package com.schoolcloud.front.config;

import cn.hutool.core.util.StrUtil;
import com.schoolcloud.common.util.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.*;
@Component
@Slf4j
public class SaTokenWebSocketHandler extends TextWebSocketHandler {

    // 存储所有连接的会话
    private static final Set<WebSocketSession> sessions =
            Collections.synchronizedSet(new HashSet<>());

    // 存储用户ID与session的映射关系（线程安全）
    private static final Map<String, WebSocketSession> userSessionMap =
            Collections.synchronizedMap(new HashMap<>());

    // 连接建立时调用 - 从请求头获取user_id并关联session
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String userId = UserContext.getUser();
        if (StrUtil.isNotBlank(userId)) {
            // 2. 存储session和用户ID的映射关系
            sessions.add(session);
            userSessionMap.put(userId, session);
            // 3. 向当前用户发送连接成功消息
            session.sendMessage(new TextMessage("用户[" + userId + "]连接成功！"));
            System.out.println("用户[" + userId + "]已建立WebSocket连接");
        } else {
            // 如果无法获取user_id，关闭连接
            session.close(CloseStatus.POLICY_VIOLATION.withReason("无法获取用户身份信息"));
        }
    }

    // 接收消息时调用
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        String userId = getUserIdBySession(session);
        System.out.println("收到用户[" + userId + "]的消息：" + payload);
        // 定向消息处理（格式: @目标用户ID:消息内容）
        if (payload.startsWith("@")) {
            handleDirectMessage(payload);
        } else {
            // 广播消息给所有连接
            broadcastMessage("用户[" + userId + "]说：" + payload);
        }
    }

    // 连接关闭时清理映射关系
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String userId = getUserIdBySession(session);
        sessions.remove(session);
        if (userId != null) {
            userSessionMap.remove(userId);
            System.out.println("用户[" + userId + "]已断开WebSocket连接");
        }
    }


    // 根据session反向获取用户ID
    private String getUserIdBySession(WebSocketSession session) {
        for (Map.Entry<String, WebSocketSession> entry : userSessionMap.entrySet()) {
            if (entry.getValue().getId().equals(session.getId())) {
                return entry.getKey();
            }
        }
        return null;
    }

    // 广播消息给所有在线用户
    public void broadcastMessage(String message) throws IOException {
        for (WebSocketSession session : sessions) {
            if (session.isOpen()) {
                session.sendMessage(new TextMessage(message));
            }
        }
    }

    // 向指定用户发送消息
    public boolean sendMessageToUser(String userId, String message) throws IOException {
        WebSocketSession session = userSessionMap.get(userId);
        if (session != null && session.isOpen()) {
            session.sendMessage(new TextMessage(message));
            return true;
        }
        return false;
    }

    // 处理定向消息
    private void handleDirectMessage(String payload) throws IOException {
        try {
            // 解析格式: @目标用户ID:消息内容
            String[] parts = payload.split(":", 2);
            if (parts.length == 2) {
                String targetUserId = parts[0].substring(1); // 去除@符号
                String messageContent = parts[1];
                boolean sent = sendMessageToUser(targetUserId, "收到私信：" + messageContent);
                if (!sent) {
                    log.error("目标用户[" + targetUserId + "]不在线");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("处理定向消息失败：{}",e.getMessage());
        }
    }
}
